package com.linkai.JUC._07_queue;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.TimeUnit;

/**
 * @Description:   ArrayBlockingQueue (阻塞队列的4组API) 使用
 *                  写入：如果队列满了，就必须阻塞等待
 *                  读取：如果队列是空的，必须阻塞等待生产
 *                  实现了 BlockingQueue 接口
 * @Author: 林凯
 * @Date: 2021/10/24 20:23
 */
public class BlockingQueueDemo {

    // 抛出异常
    public static void test01() {
        //  队列的大小
        ArrayBlockingQueue arrayBlockingQueue = new ArrayBlockingQueue<>(3);

        System.out.println(arrayBlockingQueue.add("a"));
        System.out.println(arrayBlockingQueue.add("b"));
        System.out.println(arrayBlockingQueue.add("c"));

        System.out.println("========");
        System.out.println(arrayBlockingQueue.remove());
        // 查看队首元素是谁
        System.out.println(arrayBlockingQueue.element());
        System.out.println(arrayBlockingQueue.remove());
        System.out.println(arrayBlockingQueue.remove());

        // 抛出异常：IllegalStateException
//        System.out.println(arrayBlockingQueue.add("d"));
    }

    // 不抛出异常
    public static void test02() {
        ArrayBlockingQueue arrayBlockingQueue = new ArrayBlockingQueue<>(3);
        // 插入
        System.out.println(arrayBlockingQueue.offer("a"));
        System.out.println(arrayBlockingQueue.offer("b"));
        System.out.println(arrayBlockingQueue.offer("c"));
        // 不抛出异常，返回 false
//        System.out.println(arrayBlockingQueue.offer("d"));
        // 打印队首元素
        System.out.println(arrayBlockingQueue.peek());
        System.out.println("========");

        // 取出
        System.out.println(arrayBlockingQueue.poll());
        System.out.println(arrayBlockingQueue.poll());
        System.out.println(arrayBlockingQueue.poll());
        // 返回null，不抛出异常
        System.out.println(arrayBlockingQueue.poll());
    }

    // 等待，阻塞（一直阻塞）
    public static void test03() throws InterruptedException {
        ArrayBlockingQueue arrayBlockingQueue = new ArrayBlockingQueue<>(3);

        // 一直阻塞
        arrayBlockingQueue.put("a");
        arrayBlockingQueue.put("b");
        arrayBlockingQueue.put("c");
//        arrayBlockingQueue.put("d");    // 队列没有位置了，一直阻塞

        System.out.println(arrayBlockingQueue.take());
        System.out.println(arrayBlockingQueue.take());
        System.out.println(arrayBlockingQueue.take());
        // 没有这个元素的话，也会一直等待，阻塞在这里
        System.out.println(arrayBlockingQueue.take());

    }

    // 等待，阻塞（等待超时）
    public static void test04() throws InterruptedException {
        ArrayBlockingQueue arrayBlockingQueue = new ArrayBlockingQueue<>(3);

        arrayBlockingQueue.offer("a");
        arrayBlockingQueue.offer("b");
        arrayBlockingQueue.offer("c");
        // 假设往队列里面加入d，但是队列是满的，那么就等待2秒，如果2秒之后还没有位置就超时退出
//        arrayBlockingQueue.offer("d", 2, TimeUnit.SECONDS);

        System.out.println("========");

        System.out.println(arrayBlockingQueue.poll());
        System.out.println(arrayBlockingQueue.poll());
        System.out.println(arrayBlockingQueue.poll());
        // 尝试从队列里面取出，取不出的话就等待2秒；2秒之后依旧没有取到的话就退出
        System.out.println(arrayBlockingQueue.poll(2, TimeUnit.SECONDS));

    }


    public static void main(String[] args) {
        try {
            test04();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
